package net.sxnic.item.util;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sxnic.comm.CommConstant;
import net.sxnic.comm.basecode.BaseCodeUtils;
import net.sxnic.item.ItemConstants;
import net.sxnic.item.zzdw.util.ZzdwUtils;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.ContextLoader;

public class PageUtils {

	private Logger logger = LoggerFactory.getLogger(PageUtils.class);

	public static Set<String> VALIDATION_TRUE_MAP = new HashSet<String>();

	public static Map<String, String> JQUERY_VALIDATE_MESSAGE_MAP = new HashMap<String, String>();

	public static Map<String, String> JQUERY_VALIDATE_MESSAGE_RP_MAP = new HashMap<String, String>();

	public static String config_file_path = ContextLoader.getCurrentWebApplicationContext()
			.getServletContext().getRealPath("/")
			+ "config/"
			+ ItemConstants.SYSTEM_CALALOG_ALIAS + "/page_config.xml";

	public void crtValidationHtml(String subTableAlias) {
		File file = new File(config_file_path);
		SAXReader saxReader = new SAXReader();
		try {
			Document doc = saxReader.read(file);
			logger.debug("read xml file success! file :"
					+ file.getAbsolutePath());

			Element catalogElement = null;
			// 先找是否定义相应的 cate1Alias 和 cate2Code
			List<Element> listfields = doc.selectNodes("/root/subtables/"
					+ subTableAlias + "/editfields");

			// validate rules
			StringBuilder sb = new StringBuilder();
			// validate message
			StringBuilder sb1 = new StringBuilder();

			sb.append("$(function() {\n");
			sb.append("$(\"#fromId\").validate( {");
			sb.append("rules : {");

			sb1.append("message:{");
			int i = 1;
			boolean islastestOne = false;
			for (Element e : listfields) {
				if (i == listfields.size()) {
					islastestOne = true;
				}
				sb.append(crtValidationScript(e.attributeValue("name"),
						e.attributeValue("validation"), islastestOne));
				i++;
			}
			sb.append("})");

			System.out.println(sb.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String crtValidationScript(String fieldName,
			String validation, boolean islastest) {
		// required=必填,digits=整数 number=数字 date=日期 email=邮件地址
		if (StringUtils.isNotBlank(validation)) {

			String temp = fieldName + ":{";
			String[] vs = StringUtils.split(validation, ",");
			String t = "";
			for (String v : vs) {
				if (VALIDATION_TRUE_MAP.contains(v)) {
					t = t + "bean." + v + ":true,";
				} else {
					t = t + "bean." + v + ",";
				}
			}
			temp = temp + StringUtils.removeEnd(t, ",") + "},";

			if (islastest) {
				temp = StringUtils.remove(temp, ",");
			}

			return temp;
		} else {
			return "";
		}
	}

	public static String crtValidationMessage(String fieldName, String label,
			String validation, String first, String last, boolean islastest) {
		// required=必填,digits=整数 number=数字 date=日期 email=邮件地址
		if (StringUtils.isNotBlank(validation)) {

			String temp = fieldName + ":{";
			String[] vs = StringUtils.split(validation, ",");
			String t = "";
			for (String v : vs) {
				if ("required".equals(v)) {
					t = t + "required:\"请输入" + label + "\",";
				}
				// else if("rangelength".equals(v)){
				// t =
				// t+"required:\"jQuery.validator.format('请输入 一个长度介于 {0} 和 {1} 之间的字符串')"+label+"\",";
				// }else if("range".equals(v)){
				// t =
				// t+"required:\"jQuery.validator.format('请输入 一个数值介于 {0} 和 {1} 之间的字符串')"+label+"\",";
				// }else
				// if(PageUtilsTest.JQUERY_VALIDATE_MESSAGE_MAP.containsKey(v)){
				// t =
				// t+v+":\""+PageUtilsTest.JQUERY_VALIDATE_MESSAGE_MAP.get(v)+"\",";
				// }else
				// if(PageUtilsTest.JQUERY_VALIDATE_MESSAGE_RP_MAP.containsKey(v)){
				// t =
				// t+v+":\""+PageUtilsTest.JQUERY_VALIDATE_MESSAGE_MAP.get(v)+"\",";
				// }
			}
			temp = temp + StringUtils.removeEnd(t, ",") + "},";

			if (islastest) {
				temp = StringUtils.remove(temp, ",");
			}

			return temp;
		} else {
			return "";
		}
	}

	/**
	 * 为主表创建Html代码 单一页面，分页显示，统一保存
	 * 
	 * @param obj
	 */
	public String crtMdataSingleHtml(Object obj) {
		File file = new File(config_file_path);
		SAXReader saxReader = new SAXReader();
		try {
			Document doc = saxReader.read(file);
			logger.debug("read xml file success! file :"
					+ file.getAbsolutePath());

			Element catalogElement = null;
			StringBuilder sb = new StringBuilder();
			// 先找是否定义相应的page
			List<Element> pageList = doc.selectNodes("/root/mdata/page");
			for (Element page : pageList) {
				sb.append("<div class=\"" + page.attributeValue("class")
						+ "\">");

				// table
				List<Element> tableList = page.selectNodes("table");
				for (Element table : tableList) {
					sb.append("<table class=\"" + table.attributeValue("class")
							+ "\">");

					// tr
					List<Element> trList = table.selectNodes("tr");
					for (Element tr : trList) {
						sb.append("<tr>");

						List<Element> fieldList = tr.selectNodes("field");
						for (Element field : fieldList) {
							sb.append(crtMdataTdHtml(field, obj));
						}

						sb.append("</tr>");
					}

					sb.append("</table>");
				}

				sb.append("</div>");
			}

			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 为子表创建Html代码 单一页面
	 * 
	 * @param obj
	 */
	public String crtSubTableSingleHtml(Object obj, String subTableName) {
		File file = new File(config_file_path);
		SAXReader saxReader = new SAXReader();
		try {
			Document doc = saxReader.read(file);
			logger.debug("read xml file success! file :"
					+ file.getAbsolutePath());

			Element catalogElement = null;
			StringBuilder sb = new StringBuilder();
			// 先找是否定义相应的page
			List<Element> pageList = doc.selectNodes("/root/fwzwhyc/"
					+ subTableName+"/page");
			for (Element page : pageList) {
				sb.append("<div class=\"" + page.attributeValue("class")
						+ "\">");

				// table
				List<Element> tableList = page.selectNodes("table");
				for (Element table : tableList) {
					sb.append("<table class=\"" + table.attributeValue("class")
							+ "\">");

					// tr
					List<Element> trList = table.selectNodes("tr");
					for (Element tr : trList) {
						sb.append("<tr>");

						List<Element> fieldList = tr.selectNodes("field");
						for (Element field : fieldList) {
							sb.append(crtMdataTdHtml(field, obj));
						}

						sb.append("</tr>");
					}

					sb.append("</table>");
				}

				sb.append("</div>");
			}

			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	public void crtEditHtml(String subTableAlias, Object obj) {
		File file = new File(config_file_path);
		SAXReader saxReader = new SAXReader();
		try {
			Document doc = saxReader.read(file);
			logger.debug("read xml file success! file :"
					+ file.getAbsolutePath());

			Element catalogElement = null;
			// 先找是否定义相应的 cate1Alias 和 cate2Code
			List<Element> listfields = doc.selectNodes("/root/subtables/"
					+ subTableAlias + "/editfields/field");

			StringBuilder sb = new StringBuilder();

			sb.append("<tr>");
			for (Element e : listfields) {
				sb.append("<th align='right' width='"
						+ e.attributeValue("labelWidth") + "%'>"
						+ e.attributeValue("label") + "：</th>");
				sb.append("<td align='left'>" + crtFormHtml(e, obj) + "</td>");
			}
			sb.append("</tr>");

			System.out.println(sb.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String crtMdataTdHtml(Element e, Object obj) throws Exception {
		StringBuilder sb = new StringBuilder();

		if (StringUtils.isNotBlank(e.attributeValue("labelWidth"))) {
			sb.append("<td class=\"pn-flabel pn-flabel-h\"");
			// label跨列
			if (StringUtils.isNotBlank(e.attributeValue("labelColspan"))) {
				sb.append(" colspan=\"" + e.attributeValue("labelColspan")
						+ "\"");
			}

			// label的宽度
			if (StringUtils.isNotBlank(e.attributeValue("labelWidth"))) {
				sb.append(" width=\"" + e.attributeValue("labelWidth") + "%"
						+ "\"");
			}
			sb.append(">");
			sb.append(e.attributeValue("label") + "</td>");
		}

		// 跨列
		if (StringUtils.isBlank(e.attributeValue("colspan"))) {
			sb.append("<td>");
		} else {
			sb.append("<td colspan=\"" + e.attributeValue("colspan") + "\">");
		}

		if (StringUtils.isNotBlank(e.attributeValue("requiredStar"))) {
			sb.append("<span class=\"pn-frequired\">*</span>");
		}

		sb.append(crtFormHtml(e, obj) + "</td>");

		return sb.toString();
	}

	public static String crtFormHtml(Element e, Object obj) throws Exception {
		String type = e.attributeValue("type");

		if ("text".equals(type)) {
			return crtTextHtml(e, obj);
		} else if ("textarea".equals(type)) {
			return crtTextAreaHtml(e, obj);
		} else if ("select".equals(type)) {
			return crtSelectHtml(e, obj);
		} else if ("radio".equals(type)) {
			return crtRadioHtml(e, obj);
		}else if("superiorSelect".equals(type)){
			return crtSuperiorSelectHtml(e, obj);
		}

		return "";
	}
	
	public static String crtSuperiorSelectHtml(Element e, Object obj) throws Exception {
		String name = e.attributeValue("name");
		if (!StringUtils.contains(name, ".")) {
			name = "bean." + name;
		}
		return  ZzdwUtils.crtZzdwSelectHtml(name, (String)getterValue(obj,e.attributeValue("name")));
	}

	public static String crtTextHtml(Element e, Object obj) throws Exception {
		String name = e.attributeValue("name");
		if (!StringUtils.contains(name, ".")) {
			name = "bean." + name;
		}
		return "<input type='text' name='" + name + "' value='"
				+ getterValue(obj, e.attributeValue("name"))+"' class='validate["+e.attributeValue("validation")+"]' size='"+e.attributeValue("size")+"'/>";
	}

	public static String crtSelectHtml(Element e, Object obj) throws Exception {
		String name = e.attributeValue("name");
		if (!StringUtils.contains(name, ".")) {
			name = "bean." + name;
		}
		return BaseCodeUtils.createSelectHtml(name,
				e.attributeValue("sortCode"), "", "",
				getterValue(obj, e.attributeValue("name")).toString(), "", "",
				"", "", "");
	}

	public static String crtRadioHtml(Element e, Object obj) throws Exception {
		String name = e.attributeValue("name");
		if (!StringUtils.contains(name, ".")) {
			name = "bean." + name;
		}

		Map<String, String> map = CommConstant.BASECODE_MAP.get(e
				.attributeValue("sortCode"));

		if (map == null || map.size() <= 0) {
			return "";
		}

		if (StringUtils.isBlank(name)) {
			return "";
		}

		StringBuffer sb = new StringBuffer();
		for (String code : map.keySet()) {
			if (StringUtils.contains(getterValue(obj, e.attributeValue("name"))
					.toString(), code)) {
				sb.append("<input type='radio' name='" + name + "' class='validate["+e.attributeValue("validation") + "] radio' value='"
						+ code + "' checked='true' />&nbsp;" + map.get(code)
						+ "&nbsp;");
			} else {
				sb.append("<input type='radio' name='" + name + "' class='validate["+e.attributeValue("validation") + "] radio' value='"
						+ code + "' />&nbsp;" + map.get(code) + "&nbsp;");
			}
		}

		return sb.toString();
	}

	public static String crtTextAreaHtml(Element e, Object obj)
			throws Exception {
		String name = e.attributeValue("name");
		if (!StringUtils.contains(name, ".")) {
			name = "bean." + name;
		}
		return "<textarea rows='" + e.attributeValue("rows") + "' cols='"
				+ e.attributeValue("cols") + "' name='" + name + "'>"
				+ getterValue(obj, e.attributeValue("name")) + "</textarea>";
	}

	/**
	 * 根据属性名称和Obj 利用反射原理 获取对于字段的值
	 * 
	 * @param obj
	 * @param classFieldName
	 *            主表中一般用mdata.appName 子表不包括实体名
	 * @return
	 * @throws Exception
	 */
	public static Object getterValue(Object obj, String classFieldName)
			throws Exception {
		Class<? extends Object> clas = obj.getClass();
		if (StringUtils.contains(classFieldName, ".")) {
			classFieldName = StringUtils.substringAfter(classFieldName, ".");
		}
		Method method = clas.getMethod("get" + UpFirstChar(classFieldName));

		Object obj1 = method.invoke(obj);

		if (obj1 == null) {
			return "";
		} else {
			return obj1;
		}
	}

	public static String UpFirstChar(String str) {

		String first = StringUtils.left(str, 1);
		String other = StringUtils.substring(str, 1, str.length());

		return first.toUpperCase() + other;
	}

	public void crtBrowseHtml(String subTableAlias, List<Object> objs) {
		File file = new File(config_file_path);
		SAXReader saxReader = new SAXReader();
		try {
			Document doc = saxReader.read(file);
			logger.debug("read xml file success! file :"
					+ file.getAbsolutePath());

			Element catalogElement = null;
			// 先找是否定义相应的 cate1Alias 和 cate2Code
			List<Element> nodeList = doc.selectNodes("/root/subtables/"
					+ subTableAlias + "/listfields");

			if (catalogElement == null) {
				throw new Exception("没有对应大类小类节点");
			}

			List<Element> listfields = null;
			Element listfield = null;
			Iterator iter = catalogElement.elementIterator("listfields");
			if (iter.hasNext()) {
				Element e = (Element) iter.next();
				listfield = e;
				listfields = e.selectNodes("mlfield");
			}

			if (listfields == null) {
				throw new Exception("没有mlfield节点定义");
			}

			// 是否创建表头
			boolean autoCreateHead = false;
			if ("true".equals(listfield.attributeValue("autoCreateHead"))) {
				autoCreateHead = true;
			}

			// 是否显示编号 奇偶行颜色区分
			boolean crtNum = true;
			if ("false".equals(listfield.attributeValue("sequence"))) {
				autoCreateHead = true;
			}

			StringBuilder sb = new StringBuilder();

			if (autoCreateHead) {
				sb.append("<thead><tr>");
				if (crtNum) {
					sb.append("<th width='5%'>序号</th>");
				}

				for (Element e : listfields) {
					sb.append("<th width='" + e.attributeValue("width") + "%'>"
							+ e.attributeValue("label") + "</th>");
				}
				sb.append("</tr></thead>");
			}

			sb.append("<tbody>");
			int i = 1;
			for (Object obj : objs) {

				sb.append("<tr>");

				if (crtNum) {
					sb.append("<td>" + i + "</td>");
				}

				for (Element e : listfields) {
					sb.append("<td>" + e.attributeValue("label") + "</td>");
				}

				sb.append("</tr>");
				i++;
			}
			sb.append("</tr></tbody>");

		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
